#ifndef __MESSAGE_DIGEST__
#define __MESSAGE_DIGEST__

#include <cstdint>
#include <string>

class MessageDigest {
private:
	int mType;
	unsigned int mSize;
	MessageDigest *mAlgorithm;

protected:
	MessageDigest(int type, unsigned int size) {
		mAlgorithm = NULL;
		mType = type;
		mSize = size;
	}
	MessageDigest(const MessageDigest &md){}
	MessageDigest& operator=(const MessageDigest &md){}

public:
	explicit MessageDigest(int type);
	virtual ~MessageDigest() {
		if (mAlgorithm!=NULL) delete mAlgorithm;
		mAlgorithm = NULL;
	}

	int getType(){return mType;}
	unsigned int getSize(){return mSize;}
	virtual void init(){mAlgorithm->init();}
	virtual void update(const void *data, unsigned int size){mAlgorithm->update(data, size);}
	virtual void final(){mAlgorithm->final();}
	virtual const unsigned char *getDigest(){return mAlgorithm->getDigest();}
	const unsigned char *digest(const void *data, unsigned int size);
	void digestHex(char *hex){digestHex(hex, getDigest(), getSize());}
	const std::string getDigestHex(){return digestHex(getDigest(), mSize);}

	static const int TYPE_UNKNOWN;
	static const int TYPE_MD5;
	static const int TYPE_SHA1;
	static const int TYPE_SHA256;
	static void digestHex(char *hex, const unsigned char *digest, unsigned int size);
	static const std::string digestHex(const unsigned char *digest, unsigned int size);
};

#endif
